﻿using System;
using System.Drawing;
using System.Collections.Generic;
using System.Xml;
using System.IO;

namespace MaterialEditor
{
    class CharInfo
    {
        public Rectangle rect;

        public char c;

        public float offset_y;
    }

    public class SpriteFont
    {
        Dictionary<char, CharInfo> char_map = new Dictionary<char, CharInfo>();

        int size;

        Texture2D texture;

        public SpriteFont(string filename)
        {
            // allocate an xml document and load-in values from it
            XmlDocument doc = new XmlDocument();
            doc.Load(filename);

            //// grab root node
            XmlNode root = doc.FirstChild;
            //root = root->NextSiblingElement();
            root = root.NextSibling;

            //// get the 'chars' element out of the file
            XmlNode char_root = root.SelectSingleNode("chars");

            //// allocate an iterator-pointer for each char defined in this document
            XmlNode char_iter = char_root.FirstChild;

            //// while there is still a charecter left to be read...
            while (char_iter != null)
            {
                //    // load-in this char
                LoadChar(char_iter, char_map);

                //    // go to the next node in the document
                //    char_iter = (TiXmlElement*)char_iter->NextSibling();
                char_iter = char_iter.NextSibling;
            }

            //// find the 'pages' node, the node that stores the filename of this font
            XmlNode pages_nodes = root.SelectSingleNode("pages");
            pages_nodes = pages_nodes.SelectSingleNode("page");
            //// get the font size from the 'info' node
            XmlNode info = root.SelectSingleNode("info");
            size = int.Parse(info.Attributes["size"].Value);

            //// find the name of the file
            string imageName = "Resources\\font\\" + pages_nodes.Attributes["file"].Value;
	
            //// load-in image, based off filename
            FileStream file = new FileStream(imageName, FileMode.Open);
            texture = Texture2D.FromStream(Graphics.Instance.device, file, (int)file.Length);
        }

        public void Draw(Vector2 position, string text, float scale)
        {
            Graphics g = Graphics.Instance;

            float posX = position.X;
            for (int i = 0; i < text.Length; i++)
            {
                CharInfo c = char_map[text[i]];
                g.DrawTexturedRect(new Rectangle((int)posX, (int)position.Y, c.rect.Width, c.rect.Height), texture, scale,
                    c.rect.X / (float)texture.Description.Width,
                    c.rect.Y / (float)texture.Description.Height,
                    c.rect.Width / (float)texture.Description.Width,
                    c.rect.Height / (float)texture.Description.Height);

                posX += c.rect.Width * scale;
            }
        }

        private void LoadChar(XmlNode node, Dictionary<char, CharInfo> chars)
        {
            //// allocate values for this rect
            int x, y, width, height;

            //// pull rect values out of file
            x = int.Parse(node.Attributes["x"].Value);
            y = int.Parse(node.Attributes["y"].Value);
            width = int.Parse(node.Attributes["width"].Value);
            height = int.Parse(node.Attributes["height"].Value);

            //// create the rectangle for this char
            Rectangle r = new Rectangle(x, y, width, height);

            //// find which char this rectangle is for
            char char_index = (char)int.Parse(node.Attributes["id"].Value);

            //// find the y offset for this charecter
            float offset_y = float.Parse(node.Attributes["yoffset"].Value);

            //// push the char and its info into the map
            chars.Add(char_index, new CharInfo());
            chars[char_index].offset_y = offset_y;
            chars[char_index].rect = r;
            chars[char_index].c = char_index;
        }

    }
}